<?php

namespace App\Jobs;

use App\Enums\SmsEnum;
use App\Helpers\ValidatorTool;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;
use Overtrue\EasySms\EasySms;
use Overtrue\EasySms\Exceptions\InvalidArgumentException;
use Overtrue\EasySms\Exceptions\NoGatewayAvailableException;
use Symfony\Component\Mailer\Exception\TransportException;
use function Psy\debug;

class SmsSend implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected string $mobile;
    protected array $queueData;
    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct(string $mobile, array $queueData)
    {
        $this->onQueue(SmsEnum::SMS_QUEUE_KEY);
        $this->mobile = $mobile;
        $this->queueData = $queueData;
    }
    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        if(\config('sms.is_send_sms')){
            self::sendToMobileNotice($this->mobile,$this->queueData);
        }else{
            self::updateSendStatus($this->queueData['id'], 3, 0, '发送成功', true);
        }

    }
    /**
     * 发送短信验证码
     * @param string $mobile
     * @param array $data
     * @return bool
     */
    protected static function sendToMobileNotice(string $mobile, array $data): bool
    {
//        if (config('app.debug')){
//            self::updateSendStatus($data['id'], 3, 0, '发送成功', true);
//            return true;
//        }
        try {
            $easySms = new EasySms(Config::get('easysms'));
            $easySms->send($mobile, [
                'content' => $data['content'],
                'template' => function ($gateway) {
                    if ($gateway->getName() == 'aliyun') {
                        return 'SMS_470520146';
                    }
                    return '608605';
                },
                'data' => function ($gateway)use($data) {
                    if ($gateway->getName() == 'aliyun') {
                        return [
                            'code' => $data['code'],   // 模板参数，多个参数使用 `,` 分割，模板无参数时可为空
//                            'product' => '',  // 用户 ID，随状态报告返回，可为空
                        ];
                    }
                    return [
                        'params' => $data['code'] . "," . $data['time_second'],
                    ];
                },
            ]);
            self::updateSendStatus($data['id'], 3, 0, '发送成功', true);
            return true;
        } catch (InvalidArgumentException $e) {
            $message = $e->getMessage();
            Log::info('送短信失败：' . $message, $data);
            self::updateSendStatus($data['id'], 3, $e->getCode(), '发送失败', false);
        } catch (NoGatewayAvailableException $exception) {// 返回所有 API 的结果，结构同上
            $message = $exception->getLastException()->getMessage();
            Log::info('送短信失败：' . $message, $data);
            self::updateSendStatus($data['id'], 3, $exception->getCode(), '发送失败', false);
        }
        return false;
    }

    /**
     * 更新短信发送状态。
     *
     * @param int $id 短信记录 ID。
     * @param int $channelId 短信渠道 ID。
     * @param int $errCode 错误码。
     * @param string $errMsg 错误消息。
     * @param bool $status 发送状态。
     *
     * @return void
     */
    protected static function updateSendStatus(int $id, int $channelId, int $errCode, string $errMsg, bool $status)
    {
        $upData = [
            'error_code' => $errCode,
            'error_msg' => mb_substr($errMsg, 0, 255, 'UTF-8'),
            'sms_status' => $status ? SmsEnum::SEND_STATUS_SENT : SmsEnum::SEND_STATUS_FAILED,
            's_time' => now(),
            'channel_id' => $channelId
        ];
        $affectRows = DB::table('sms_sendlog')->where(['id' => $id])->update($upData);
        if ($affectRows == 0) {
            Log::error("短信记录更新失败:id->{$id}", $upData);
        }
    }
}
